package com.ctbri.JWLetter.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import com.alibaba.fastjson.JSONException;

/**
 * 类型转换工具类
 * 
 * @author Hogan
 *
 */
public class TypeUtils {

	/**
	 * 强制类型转换
	 * 
	 * @param obj
	 * @param clazz
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static final <T> T castType(Object obj, Class<T> clazz) {

		if (obj == null) {
			return null;
		}
		if (clazz == null) {
			throw new IllegalArgumentException("clazz is null");
		}
		if (clazz == obj.getClass()) {
			return (T) obj;
		}

		if (clazz == boolean.class || clazz == Boolean.class) {
			return (T) TypeUtils.castToBoolean(obj);
		}

		if (clazz == int.class || clazz == Integer.class) {
			return (T) TypeUtils.castToInt(obj);
		}

		if (clazz == long.class || clazz == Long.class) {
			return (T) TypeUtils.castToLong(obj);
		}

		if (clazz == double.class || clazz == Double.class) {
			return (T) TypeUtils.castToDouble(obj);
		}

		if (clazz == String.class) {
			return (T) TypeUtils.castToString(obj);
		}

		if (clazz == Date.class) {
			return (T) TypeUtils.castToDate(obj);
		}
		return null;
	}

	/**
	 * 强制转换为字符串
	 * 
	 * @param value
	 * @return
	 */
	public static final String castToString(Object value) {
		if (value == null) {
			return null;
		}

		return value.toString();
	}

	/**
	 * 强制转换为double
	 * 
	 * @param value
	 * @return
	 */
	public static final Double castToDouble(Object value) {
		if (value == null) {
			return null;
		}

		if (value instanceof Number) {
			return ((Number) value).doubleValue();
		}

		if (value instanceof String) {
			String strVal = value.toString();
			if (strVal.length() == 0) {
				return null;
			}
			return Double.parseDouble(strVal);
		}
		throw new JSONException("can not cast to double, value : " + value);
	}

	/**
	 * 强制转换为日期类型
	 * 
	 * @param value
	 * @return
	 */
	public static final Date castToDate(Object value) {
		if (value == null) {
			return null;
		}

		if (value instanceof Calendar) {
			return ((Calendar) value).getTime();
		}

		if (value instanceof Date) {
			return (Date) value;
		}

		long longValue = -1;

		if (value instanceof Number) {
			longValue = ((Number) value).longValue();
		}

		if (value instanceof String) {
			String strVal = (String) value;

			if (strVal.indexOf('-') != -1) {
				String format;
				if (strVal.length() == 10) {
					format = "yyyy-MM-dd";
				} else if (strVal.length() == "yyyy-MM-dd HH-mm-ss".length()) {
					format = "yyyy-MM-dd HH-mm-ss";
				} else {
					format = "yyyy-MM-dd HH-mm-ss.SSS";
				}

				SimpleDateFormat dateFormat = new SimpleDateFormat(format);
				try {
					return (Date) dateFormat.parse(strVal);
				} catch (ParseException e) {
					throw new JSONException("can not cast to Date, value : " + strVal);
				}
			}

			if (strVal.length() == 0) {
				return null;
			}

			longValue = Long.parseLong(strVal);
		}

		if (longValue < 0) {
			throw new JSONException("can not cast to Date, value : " + value);
		}

		return new Date(longValue);
	}

	/**
	 * 强制转换为Long
	 * 
	 * @param value
	 * @return
	 */
	public static final Long castToLong(Object value) {
		if (value == null) {
			return null;
		}

		if (value instanceof Number) {
			return ((Number) value).longValue();
		}

		if (value instanceof String) {
			String strVal = (String) value;
			if (strVal.length() == 0) {
				return null;
			}

			try {
				return Long.parseLong(strVal);
			} catch (NumberFormatException ex) {
				//
			}
		}

		throw new JSONException("can not cast to long, value : " + value);
	}

	public static final Integer castToInt(Object value) {
		if (value == null) {
			return null;
		}

		if (value instanceof Integer) {
			return (Integer) value;
		}

		if (value instanceof Number) {
			return ((Number) value).intValue();
		}

		if (value instanceof String) {
			String strVal = (String) value;
			if (strVal.length() == 0) {
				return null;
			}

			return Integer.parseInt(strVal);
		}

		throw new JSONException("can not cast to int, value : " + value);
	}

	public static final Boolean castToBoolean(Object value) {
		if (value == null) {
			return null;
		}

		if (value instanceof Boolean) {
			return (Boolean) value;
		}

		if (value instanceof Number) {
			return ((Number) value).intValue() == 1;
		}

		if (value instanceof String) {
			String str = (String) value;
			if (str.length() == 0) {
				return null;
			}

			if ("true".equals(str)) {
				return Boolean.TRUE;
			}
			if ("false".equals(str)) {
				return Boolean.FALSE;
			}

			if ("1".equals(str)) {
				return Boolean.TRUE;
			}
		}

		throw new JSONException("can not cast to int, value : " + value);
	}

}
